//
//  HD_LD_ClusterAlgorithm.m
//  HDWuDaDaoServiceCenter
//
//  Created by mac on 2017/7/12.
//  Copyright © 2017年 HDNiuKuiming. All rights reserved.
//

#import "HD_LD_ClusterAlgorithm.h"
#import "HD_LD_ClusterAnnotion.h"

#define PIN_WIDTH  35.0             //POI宽度
#define PIN_HEIGHT 40.0             //POI高度
#define PointParameter 8.0      //Poi初始坐标是需要的参数
@implementation HD_LD_ClusterAlgorithm

- (id)init {
    self = [super init];
    if (self) {
        _quadtree = [[HD_LD_ClusterQuadtree alloc] initWithRect:CGRectZero];
        _quadItems = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)addItem:(HDAnnotation*)clusterItem{
    
    @synchronized(_quadtree) {
        [_quadItems addObject:clusterItem];
        [_quadtree addItem:clusterItem];
        //        NSLog(@"%@", _quadtree.quadItems);
    }
}

/**
 *  cluster算法核心
 * @param zoomLevel map的级别
 */
- (NSArray*)getClusters:(CGFloat) zoomLevel withRect:(CGRect)rect {
    if (zoomLevel >= 8) {
        return _quadItems;
    }
    NSMutableArray *results = [NSMutableArray array];
    //可聚合的距离
    NSMutableSet *visitedCandidates = [NSMutableSet set];
    NSMutableDictionary *distanceToCluster = [NSMutableDictionary dictionary];
    NSMutableDictionary *itemToCluster = [NSMutableDictionary dictionary];
    
    @synchronized(_quadtree) {
        for (HDAnnotation *annotion in _quadItems) {
            
            //annotion已经添加到另一cluster中
            if ([visitedCandidates containsObject:annotion]) {
                continue;
            }
            HD_LD_ClusterAnnotion *cluster = [[HD_LD_ClusterAnnotion alloc] init];
            CGPoint p = CGPointMake((annotion.originalPoint.x/PointParameter)*zoomLevel, (annotion.originalPoint.y/PointParameter)*zoomLevel);
            annotion.point = p;
            cluster.annnotion = annotion;
            CGRect searchRect = [self getRectWithPt:annotion.point];
            _quadtree.rect = rect;
            NSMutableArray *items = (NSMutableArray*)[_quadtree searchInRect:searchRect withZoomLevel:zoomLevel];
            
            if (items.count == 1) {
                [cluster.clusterItems addObject:annotion];
                [results addObject:cluster];
                [visitedCandidates addObject:annotion];
                [distanceToCluster setObject:[NSNumber numberWithDouble:0] forKey:[NSNumber numberWithLongLong:annotion.hash]];
                continue;
            }
            
            for (HDAnnotation *quadItem in items) {
                NSNumber *existDistache = [distanceToCluster objectForKey:[NSNumber numberWithLongLong:quadItem.hash]];
                CGFloat distance = [self getDistanceSquared:annotion.point point:quadItem.point];
                if (existDistache != nil) {
                    if (existDistache.floatValue < distance) {
                        continue;
                    }
                    HD_LD_ClusterAnnotion *existCluster = [itemToCluster objectForKey:[NSNumber numberWithLongLong:quadItem.hash]];
                    [existCluster.clusterItems removeObject:quadItem];
                }
                [distanceToCluster setObject:[NSNumber numberWithDouble:distance] forKey:[NSNumber numberWithLongLong:quadItem.hash]];
                [cluster.clusterItems addObject:quadItem];
                [itemToCluster setObject:cluster forKey:[NSNumber numberWithLongLong:quadItem.hash]];
            }
            [visitedCandidates addObjectsFromArray:items];
            [results addObject:cluster];
        }
    }
    return results;
}

- (CGRect)getRectWithPt:(CGPoint) pt {
    /*
     *以当前点的坐标和宽高为基础，只要有和当前点相交的点就聚合
     */
    return CGRectMake(pt.x-PIN_WIDTH, pt.y-PIN_HEIGHT, PIN_WIDTH*2.0, PIN_HEIGHT*2.0);
}

//两点之间的距离
- (CGFloat)getDistanceSquared:(CGPoint) pt1 point:(CGPoint) pt2 {
    return (pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y);
}

@end
